package com.hongsuan.pplive.mobileAPI.room;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.cnjson.common.config.Global;
import com.cnjson.db.persistence.Page;
import com.cnjson.common.utils.CacheUtils;
import com.cnjson.common.utils.Encodes;
import com.cnjson.common.utils.IdGen;
import com.cnjson.common.utils.StringUtils;
import com.cnjson.common.web.BaseController;
import com.google.common.collect.Lists;
import com.hongsuan.pplive.mobileAPI.utils.AuthenServerUtils;
import com.hongsuan.pplive.mobileAPI.utils.Convertor;
import com.hongsuan.pplive.mobileAPI.utils.JsonUtils;
import com.hongsuan.pplive.mobileAPI.utils.NetworkUtils;
import com.hongsuan.pplive.mobileAPI.utils.SignatureUtils;
import com.hongsuan.pplive.mobileAPI.vo.Anchor;
import com.hongsuan.pplive.mobileAPI.vo.ClickAlikeVo;
import com.hongsuan.pplive.mobileAPI.vo.GoldContribution;
import com.hongsuan.pplive.mobileAPI.vo.Member;
import com.hongsuan.pplive.mobileAPI.vo.ReturnList;
import com.hongsuan.pplive.mobileAPI.vo.ReturnObject;
import com.hongsuan.pplive.mobileAPI.vo.ReturnStatus;
import com.hongsuan.pplive.mobileAPI.vo.Room;
import com.hongsuan.pplive.mobileAPI.vo.RoomRecording;
import com.hongsuan.pplive.mobileAPI.vo.Special;
import com.hongsuan.pplive.mobileAPI.vo.Status;
import com.hongsuan.pplive.mobileAPI.vo.UserVo;
import com.hongsuan.pplive.modules.live.entity.LiveClickAlike;
import com.hongsuan.pplive.modules.live.entity.LiveGoldContribution;
import com.hongsuan.pplive.modules.live.entity.LivePushStreamUrl;
import com.hongsuan.pplive.modules.live.entity.LiveRecording;
import com.hongsuan.pplive.modules.live.entity.LiveRoom;
import com.hongsuan.pplive.modules.live.entity.LiveTipOffs;
import com.hongsuan.pplive.modules.live.entity.LiveUserLog;
import com.hongsuan.pplive.modules.live.entity.LiveUserRoom;
import com.hongsuan.pplive.modules.live.service.LiveClickAlikeService;
import com.hongsuan.pplive.modules.live.service.LiveGoldContributionService;
import com.hongsuan.pplive.modules.live.service.LivePushStreamUrlService;
import com.hongsuan.pplive.modules.live.service.LiveRecordingService;
import com.hongsuan.pplive.modules.live.service.LiveRoomService;
import com.hongsuan.pplive.modules.live.service.LiveTipOffsService;
import com.hongsuan.pplive.modules.live.service.LiveUserLogService;
import com.hongsuan.pplive.modules.live.service.LiveUserRoomService;

@Controller
@RequestMapping("/v2/room")
public class RoomAPIController extends BaseController {

	@Autowired
	private LiveRoomService roomService;

	@Autowired
	private LiveGoldContributionService liveGoldContributionService;

	@Autowired
	private LiveClickAlikeService liveClickAlikeService;

	@Autowired
	private LiveRecordingService liveRecordingService;

	@Autowired
	private LiveUserRoomService liveUserRoomService;

	@Autowired
	private LiveTipOffsService liveTipOffsService;

	@Autowired
	private LivePushStreamUrlService livePushStreamUrlService;

	@Autowired
	private LiveUserLogService userLogService;


	private static final String USER_CACHE = "userCache";
	@RequestMapping(value = "/getSig", method = RequestMethod.GET)
	public @ResponseBody String getSig(@RequestParam("userId") String userId) {
		ReturnObject ret = new ReturnObject();
		try {
			// isExisted = AuthenServerUtils.checkUserExisted(userId);
			Member member = AuthenServerUtils.getUser(userId);
			String sig = "";
			if (member != null) {
				sig = (String) CacheUtils.get(USER_CACHE, userId);
				if (StringUtils.isEmpty(sig)) {
					sig = SignatureUtils.getSig(userId, TXConstant.SDK_APP_ID, TXConstant.SDK_EXPIRE_TIME);
					CacheUtils.put(USER_CACHE, userId, sig);
				}
				member.setSig(sig);
				ret.setCode(0);
				ret.setMessage(Global.SUCCESS);
				ret.setObject(member);
			} else {
				
				ret.setCode(1);
				ret.setMessage("The userId is not exist, please login first!");
			}
		} catch (Exception e) {
			logger.error(e.getMessage());
		}
		return ret.toString();

	}

	/**
	 * Save the PushStreamUrl the server.
	 * 
	 * @param roomId
	 *            the room id.
	 * @param streamUrl
	 *            the url.
	 * @return
	 */
	@RequestMapping(value = "/savePushStreamUrl", method = RequestMethod.POST)
	public @ResponseBody String savePushStreamUrl(@RequestParam("roomId") String roomId,
			@RequestParam("streamUrl") String streamUrl, @RequestParam("channelId") String channelId) {
		Status ret = new Status();
		try {
			LivePushStreamUrl livePushStreamUrl = livePushStreamUrlService.getByRoomId(roomId);
			if (livePushStreamUrl == null) {
				livePushStreamUrl = new LivePushStreamUrl();
			}
			livePushStreamUrl.setStreamUrl(streamUrl);
			livePushStreamUrl.setRoomId(roomId);
			livePushStreamUrlService.save(livePushStreamUrl);
			LiveRoom liveRoom = roomService.get(roomId);
			if (liveRoom != null) {
				liveRoom.setChannelId(channelId);
				roomService.save(liveRoom);
			}
			ret.setCode(0);
			ret.setMessage(Global.SUCCESS);
		} catch (Exception e) {
			logger.error(e.getMessage());
			ret.setCode(10);
			ret.setMessage(Global.FAILED);
		}
		return JsonUtils.toJson(ret);
	}

	/**
	 * 获取推流URL
	 * 
	 * @param roomId
	 * @return
	 */
	@RequestMapping(value = "/getStreamUrl", method = RequestMethod.GET)
	public @ResponseBody String getStreamUrl(@RequestParam("roomId") String roomId) {
		ReturnStatus ret = new ReturnStatus();
		try {
			LiveRoom liveRoom = roomService.get(roomId);
			if (liveRoom == null) {
				ret.setMessage("The room is not exist!");
				ret.setCode(1);
				return JsonUtils.toJson(ret);
			}
			if (liveRoom.getState() != 1) {
				ret.setMessage("The room is close!");
				ret.setCode(2);
				return JsonUtils.toJson(ret);
			}
			String streamUrl = "";
			LivePushStreamUrl livePushStreamUrl = livePushStreamUrlService.getByRoomId(roomId);
			if (livePushStreamUrl != null) {
				streamUrl = livePushStreamUrl.getStreamUrl();
			}
			Map<String, Object> obj = new HashMap<>();
			obj.put("streamUrl", streamUrl);
			ret.setItem(obj);
			ret.setMessage(Global.SUCCESS);
			ret.setCode(0);

		} catch (Exception e) {
			ret.setMessage(Global.FAILED);
			ret.setCode(10);
			logger.error(e.getMessage());
		}
		return ret.toString();
	}

	/**
	 * Apply the room number with room owner user id.
	 * 
	 * @param owner
	 *            the owner user id.
	 * @return THE ROOM Object JSON
	 * 
	 *         <code>{"code":0,"message":"success","Room":{"id":"11793","userId":
	 *         "8593817701","userName":"user111","onlineNumber":1}} </code>
	 */
	@RequestMapping(value = "/apply", method = RequestMethod.GET)
	public @ResponseBody String apply(@RequestParam("owner") String owner) {
		ReturnObject ret = new ReturnObject();
		try {
			String id = "";
			LiveRoom liveRoom = null;
			// User user = systemService.getUser(owner);
			Member member = AuthenServerUtils.getUser(owner);
			if (!member.getType().equalsIgnoreCase("anchor")) {
				ret.setCode(1);
				ret.setMessage("You are not anchor user type,not allow to apply !");
				return ret.toString();
			}
			if (member != null) {
				liveRoom = roomService.getByOwner(owner);
				if (liveRoom == null) {
					do {
						id = IdGen.generateId(5);
						if (!id.startsWith("0") && !roomService.checkExisted("id", id)) {
							break;
						}
					} while (true);
					liveRoom = new LiveRoom();
					liveRoom.setType(0);
					liveRoom.setId(id);
					liveRoom.setState(0);
					liveRoom.setOnlineNumber(1L);
					liveRoom.setNewRecord(true);
					liveRoom.setUserId(owner);
					liveRoom.setCreateDate(new Date());
				} else {
					if (liveRoom.getType() == null) {
						liveRoom.setType(0);
					}
					liveRoom.setState(1);
					liveRoom.setOnlineNumber(1L);
					liveRoom.setNewRecord(false);
					liveRoom.setUpdateById(owner);
					liveRoom.setUpdateDate(new Date());
				}
				liveRoom.setAvatar(member.getAvatar());
				liveRoom.setUserName(member.getNickname());
				roomService.save(liveRoom);
				Room vo = Convertor.roomConvert2Vo(liveRoom);
				ret.setCode(0);
				ret.setMessage(Global.SUCCESS);
				ret.setObject(vo);
			}
		} catch (Exception e) {
			logger.error(e.getMessage());
			ret.setCode(10);
			ret.setMessage(Global.FAILED);
			e.printStackTrace();
		}
		return ret.toString();
	}

	/**
	 * 客户端创建房间之后通知服务端所调用的接口
	 * 
	 * @param {@link
	 * 			Room} JSON object. 创建者用户id.
	 * @return {@link Room} JSON object.
	 */
	@RequestMapping(value = "/create", method = RequestMethod.POST)
	public @ResponseBody String create(@RequestParam("room") String roomJson, HttpServletRequest request) {

		return updateRoom(roomJson, request, true);
	}

	private String updateRoom(String roomJson, HttpServletRequest request, boolean isNew) {
		ReturnObject ret = new ReturnObject();
		ret.setObject(null);
		if (StringUtils.isBlank(roomJson)) {
			ret.setMessage("You post room object structrue is not allow empty or null !");
			ret.setCode(5);
			return ret.toString();
		}
		try {
			// logger.info("Create room the post data1======>" + roomJson);
			LiveRoom liveRoom = new LiveRoom();
			String param = Encodes.urlDecode(Encodes.unescapeHtml(roomJson));
			logger.info("Create room the post data======>" + param);
			Room vo = JsonUtils.fromJson(param, Room.class);
			boolean isExisted = AuthenServerUtils.checkUserExisted(vo.getUserId());
			if (!isExisted) {
				ret.setMessage("The room owner user is not exist!");
				ret.setCode(1);
				return JsonUtils.toJson(ret);
			}
			liveRoom = roomService.get(vo.getId());
			if (liveRoom == null || StringUtils.isBlank(vo.getChatId())) {
				ret.setMessage("The room should be apply first!");
				ret.setCode(2);
				return JsonUtils.toJson(ret);
			}
			vo.setState(1);
			liveRoom = Convertor.voConvert2LiveRoom(vo);
			if (isNew) {
				liveRoom.setState(1);
				// liveRoom.setOnlineNumber(1L);
				// VirtualUserJoinRoomThread virtualUser = new
				// VirtualUserJoinRoomThread(liveRoom);
				// sendMsgPool.execute(virtualUser);

				CompletableFuture<Void> future = CompletableFuture.runAsync(new VirtualUserEnterRoom(liveRoom));
				if (future.isDone()) {
					logger.info("------>future is done!");
				}
			}

			/**
			 * 图片上传直接上传第三方文件服务器中。
			 */
			// if (request != null && request instanceof
			// MultipartHttpServletRequest) {
			// MultipartHttpServletRequest multipartRequest =
			// (MultipartHttpServletRequest) request;
			// if (multipartRequest != null) {
			// MultipartFile mf = multipartRequest.getFile("file");
			// if (mf != null) {
			// if (!UploadFileUtils.isPicture(mf.getOriginalFilename())) {
			// ret.setCode(2);
			// ret.setMessage("File format is not correct!");
			// logger.error("File format is not correct!");
			// return ret.toString();
			// }
			// if (!UploadFileUtils.validateSize(mf)) {
			// ret.setCode(3);
			// ret.setMessage("File size exceeds the allowable range!");
			// logger.error("File size exceeds the allowable range!");
			// return ret.toString();
			// }
			//
			// UploadFile upload = UploadFileUtils.dealFilePath(request,
			// liveRoom.getUserId(),
			// mf.getOriginalFilename());
			// String realPath = UploadFileUtils.getRequestRealPath(request,
			// upload.getRelativePath());
			// File file = new File(realPath);
			// mf.transferTo(file);
			// liveRoom.setPictureUrl(upload.getRelativePath());
			// }
			// }
			// }

			roomService.save(liveRoom);
			ret.setCode(0);
			ret.setMessage(Global.SUCCESS);
			ret.setObject(vo);
		} catch (Exception e) {
			ret.setCode(10);
			ret.setMessage(Global.FAILED);
			e.printStackTrace();
			logger.error(e.getMessage());
		}
		return ret.toString();
	}

	@RequestMapping(value = "/update", method = RequestMethod.POST)
	public @ResponseBody String update(@RequestParam("room") String roomJson, HttpServletRequest request) {
		return updateRoom(roomJson, request, false);
	}

	/**
	 * 房间销毁
	 * 
	 * @param roomId
	 *            房间ID
	 * @param owner
	 *            房间主播ID
	 * @return 成功是否json结构
	 */
	@RequestMapping("/destroy")
	public @ResponseBody String destroy(@RequestParam("roomId") String roomId, @RequestParam("owner") String owner) {
		ReturnStatus ret = new ReturnStatus();
		try {
			LiveRoom room = roomService.get(roomId);
			if (room == null) {
				ret.setCode(1);
				ret.setMessage("The room is no exist!");
				return JsonUtils.toJson(ret);
			}
			if (!room.getUserId().equals(owner)) {
				ret.setCode(2);
				ret.setMessage("You do not allow to destroy other's room!");
				return JsonUtils.toJson(ret);
			}
			room.setState(2);// 关闭退出
			room.setOnlineNumber(0L);
			ret.setCode(0);
			ret.setMessage(Global.SUCCESS);
			roomService.save(room);
			liveUserRoomService.deleteVirtualUsers(roomId);
			// roomService.delete(room);
//			CompletableFuture<String> resultFeture = CompletableFuture.supplyAsync(() -> {
//			
//				return Global.SUCCESS;
//			});
//			resultFeture.exceptionally(throwable -> {
//				logger.error("Unrecoverable error", throwable);
//				return null;
//			});
//			resultFeture.complete(Global.SUCCESS);


		} catch (Exception e) {
			logger.error(e.getMessage());
			ret.setCode(10);
			ret.setMessage(Global.FAILED);
		}
		return ret.toString();
	}

	/**
	 * 普通用户加入房间
	 * 
	 * @param roomId
	 *            房间 id.
	 * @param userId
	 *            加入者 user id.
	 * @return
	 */
	@RequestMapping(value = "/join", method = RequestMethod.GET)
	public @ResponseBody String join(@RequestParam("roomId") String roomId, @RequestParam("userId") String userId,
			HttpServletRequest request) {
		ReturnStatus ret = new ReturnStatus();
		try {
			LiveRoom liveRoom = roomService.get(roomId);
			if (liveRoom == null) {
				ret.setMessage("The room is not exist!");
				ret.setCode(1);
				return JsonUtils.toJson(ret);
			}
			boolean isExisted = AuthenServerUtils.checkUserExisted(userId);
			if (!isExisted) {
				ret.setMessage("The room join user is not exist!");
				ret.setCode(2);
				return JsonUtils.toJson(ret);
			}

			CompletableFuture<String> resultFeture = CompletableFuture.supplyAsync(() -> {
				try {
					LiveUserRoom userRoom = new LiveUserRoom();
					userRoom.setUserId(userId);
					userRoom.setRoomId(roomId);
					if (!liveUserRoomService.existed(userRoom)) {
						liveUserRoomService.add(userRoom);
					}
					String ip = NetworkUtils.getIpAddr(request);
					LiveUserLog userLog = new LiveUserLog();
					userLog.setRoomId(roomId);
					userLog.setCreateDate(new Date());
					userLog.setRemoteAddr(ip);
					userLog.setUserId(userId);
					userLog.setRemarks("");
					if (!userLogService.isExist(userLog)) {
						userLogService.save(userLog);
					}
				} catch (Exception e1) {
					logger.error(e1.toString());
					return null;
				}
				return Global.SUCCESS;
			});

			// roomService.join(roomId, userId);
			String streamUrl = "";
			LivePushStreamUrl livePushStreamUrl = livePushStreamUrlService.getByRoomId(roomId);
			if (livePushStreamUrl != null) {
				streamUrl = livePushStreamUrl.getStreamUrl();
			}
			Map<String, Object> obj = new HashMap<>();
			obj.put("streamUrl", streamUrl);
			ret.setItem(obj);
			ret.setMessage(Global.SUCCESS);
			ret.setCode(0);

			if (resultFeture.isDone()) {
				logger.info("------->save log is OK!");
			}
			// new SaveUserLogThread(userLog).start();

		} catch (Exception e) {
			ret.setMessage(Global.FAILED);
			ret.setCode(10);
			logger.error(e.getMessage());
		}
		return ret.toString();
	}

	/**
	 * 普通用户退出房间
	 * 
	 * @param roomId
	 *            房间 id.
	 * @param userId
	 *            加入者 user id.
	 * @return
	 */
	@RequestMapping(value = "/leave", method = RequestMethod.GET)
	public @ResponseBody String leave(@RequestParam("roomId") String roomId, @RequestParam("userId") String userId) {
		Status ret = new Status();
		try {
			LiveRoom liveRoom = roomService.get(roomId);
			if (liveRoom == null) {
				ret.setMessage("The room is not exist!");
				ret.setCode(1);
				return JsonUtils.toJson(ret);
			}
			boolean isExisted = AuthenServerUtils.checkUserExisted(userId);
			if (!isExisted) {
				ret.setMessage("The room join user is not exist!");
				ret.setCode(2);
				return JsonUtils.toJson(ret);
			}
			roomService.leave(roomId, userId);
			ret.setMessage(Global.SUCCESS);
			ret.setCode(0);
		} catch (Exception e) {
			ret.setMessage(Global.FAILED);
			ret.setCode(10);
			logger.error(e.getMessage());
		}
		return JsonUtils.toJson(ret);
	}

	/**
	 * 查询所有房间排行列表
	 * 
	 * @param pageIndex
	 *            不是必须的，索引页面默认值为1
	 * @param pageSize
	 *            一页多少条，默认为50条
	 * @return 返回房间排行列表，默认一页取50个
	 */
	@RequestMapping(method = RequestMethod.GET, value = "/queryRooms")
	public @ResponseBody String queryRooms(
			@RequestParam(value = "pageIndex", required = false, defaultValue = "1") Integer pageIndex,
			@RequestParam(value = "pageSize", required = false, defaultValue = "50") Integer pageSize) {
		ReturnList ret = new ReturnList();
		try {
			LiveRoom liveRoom = new LiveRoom();
			liveRoom.setState(1);
			Page<LiveRoom> page = new Page<LiveRoom>(pageIndex, pageSize);
			/*
			 * page.setOrderBy("a.online_users_number desc,a.create_date desc "
			 * );
			 */
			List<LiveRoom> lists = roomService.findPage(page, liveRoom).getList();
			List<Room> vos = new ArrayList<>();
			final List<Special> spes = AuthenServerUtils.getSpecialList(null, null);
			for (LiveRoom live : lists) {
				String specialId = live.getSpecialId();
				Float goodsDiscount = 0f;
				if (StringUtils.isNotBlank(specialId) && (spes != null && spes.size() > 0)) {
					for (Special sp : spes) {
						if (specialId.equals(sp.getId().toString())) {
							live.setTitle(sp.getTitle());
							live.setPictureUrl(sp.getBanner());
							goodsDiscount = sp.getGoods_discount();
							break;
						}
					}
				}
				Room vo = Convertor.roomConvert2Vo(live);
				if (StringUtils.isNotBlank(specialId)) {
					vo.setSpecialId(specialId);
					vo.setGoodsDiscount(goodsDiscount);
				}
				vos.add(vo);
			}

			ret.setList(vos);
			ret.setCode(0);
			ret.setMessage(Global.SUCCESS);

		} catch (Exception e) {
			e.printStackTrace();
			logger.error(e.getMessage());
			ret.setCode(10);
			ret.setMessage(Global.FAILED);
		}
		return ret.toString();
	}

	/**
	 * 查询最新TAB数据，如果直播不足20条用录播数据填充满20。
	 * 
	 * @return
	 */
	@RequestMapping(method = RequestMethod.GET, value = "/queryLastRoom")
	public @ResponseBody String queryLastRoom(
			@RequestParam(value = "pageIndex", required = false, defaultValue = "1") Integer pageIndex,
			@RequestParam(value = "pageSize", required = false, defaultValue = "50") Integer pageSize) {
		ReturnList ret = new ReturnList();
		try {
			LiveRoom liveRoom = new LiveRoom();
			liveRoom.setState(1);
			List<LiveRoom> lists = roomService.findList(liveRoom);
			int size = 0;
			if (lists != null) {
				size = lists.size();
			} else {
				lists = new ArrayList<>();
			}
			if (size > 20) {
				return queryRooms(pageIndex, pageSize);
			}
			List<RoomRecording> roomRecordings = new ArrayList<>();

			// 如果正在直播的数据少于20条，用录播数据补充
			if (size < 20) {
				final List<Special> spes = AuthenServerUtils.getSpecialList(null, null);
				String specialIds = "";
				StringBuilder sb = new StringBuilder();
				for (LiveRoom lRoom : lists) {
					if (StringUtils.isNotBlank(lRoom.getSpecialId())) {
						sb.append("'" + lRoom.getSpecialId() + "',");
					}
					// set to roomRecordings ..
					RoomRecording rr = new RoomRecording();
					rr.setRoom(lRoom);
					roomRecordings.add(rr);
				}

				if (sb.length() > 0) {
					sb.setLength(sb.length() - 1);
				}
				specialIds = sb.toString();
				LiveRecording liveRecording = new LiveRecording();
				// 取近15日内的数据
				liveRecording.setDeadline(15);
				// 只是一个标识，每个分类只取一份
				liveRecording.setFileSet("flag");
				// 排除正在直播的专场
				if (StringUtils.isNotEmpty(specialIds)) {
					liveRecording.setNotInSpecialIds(specialIds);
				}
				liveRecording.setLimitNumber(20 - size);

				// 用录播数据补充
				List<LiveRecording> recordings = liveRecordingService.findList(liveRecording);
				logger.info("------------------->recording size=" + recordings.size());

				for (LiveRecording re : recordings) {
					String roomJson = re.getRoom();
					if (StringUtils.isEmpty(roomJson)) {
						continue;
					}
					roomJson = JsonUtils.placeJson(roomJson);
					LiveRoom room = JsonUtils.fromJson(roomJson, LiveRoom.class);
					if (room == null) {
						continue;
					}
					room.setState(4);// 录播状态
					String specialId = re.getSpecialId();
					Float goodsDiscount = 0f;
					if (StringUtils.isNotBlank(specialId) && (spes != null && spes.size() > 0)) {
						for (Special sp : spes) {
							if (specialId.equals(sp.getId().toString())) {
								goodsDiscount = sp.getGoods_discount();
								// 如果专场替换banner和title
								room.setTitle(sp.getTitle());
								room.setPictureUrl(sp.getBanner());
								room.setSpecialId(specialId);
								room.setGoodsDiscount(goodsDiscount);
								break;
							}
						}
					}
					RoomRecording rr = new RoomRecording();
					rr.setRoom(room);
					rr.setFileSet(re.getFileSet());
					roomRecordings.add(rr);
				}
			}
			ret.setList(roomRecordings);
			ret.setCode(0);
			ret.setMessage(Global.SUCCESS);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error(e.getMessage());
			ret.setCode(10);
			ret.setMessage(Global.FAILED);
		}
		return JsonUtils.placeJson(ret.toString());
	}

	/**
	 * 获取当前房间实例
	 * 
	 * @param roomId
	 *            房间ID
	 * @return 返回房间实例
	 */
	@RequestMapping(method = RequestMethod.GET, value = "/getRoom")
	public @ResponseBody String getRoom(@RequestParam("roomId") String roomId) {
		ReturnObject ret = new ReturnObject();
		try {
			LiveRoom liveRoom = roomService.get(roomId);
			Room vo = Convertor.roomConvert2Vo(liveRoom);
			ret.setCode(0);
			ret.setObject(vo);
			ret.setMessage(Global.SUCCESS);
		} catch (Exception e) {
			ret.setCode(10);
			ret.setMessage(Global.FAILED);
			logger.error(e.getMessage());
		}
		return ret.toString();
	}

	/**
	 * 查询获取一个专场主播列表
	 * 
	 * @param specailId
	 *            专场ID
	 * @return 专场主播列表
	 */
	@RequestMapping(method = RequestMethod.GET, value = "/querySpecialAnchor")
	public @ResponseBody String querySpecialAnchor(@RequestParam("specialId") String specialId) {

		ReturnList ret = new ReturnList();
		try {
			final List<Special> spes = AuthenServerUtils.getSpecialList(null, null);
			List<Member> vos = new ArrayList<>();
			if (spes != null && spes.size() > 0) {
				for (Special sp : spes) {
					if (sp.getId() != Long.parseLong(specialId)) {
						continue;
					}
					List<Anchor> anchors = sp.getAnchor();
					if (anchors != null && anchors.size() > 0) {
						for (Anchor anchor : anchors) {
							Long number = anchor.getMember_id();
							if (roomService.checkExisted("create_by", number.toString())) {
								Member member = AuthenServerUtils.getUser(number.toString());
								vos.add(member);
							}
						}
					}
				}
			}
			ret.setCode(0);
			ret.setList(vos);
			ret.setMessage(Global.SUCCESS);
		} catch (Exception e) {
			ret.setCode(10);
			ret.setMessage(Global.FAILED);
			logger.error(e.getMessage());
		}
		return ret.toString();
	}

	// 个人 录播7天内列表
	// 一个专场的
	/**
	 * 查询一个用户所有关注的主播房间列表
	 * 
	 * @param userId
	 *            当前用户Id
	 * @return 主播房间列表
	 */
	@RequestMapping(method = RequestMethod.GET, value = "/queryUserConcerns")
	@ResponseBody
	public String queryUserConcerns(@RequestParam("userId") String userId) {
		ReturnList ret = new ReturnList();
		try {
			List<Room> vos = new ArrayList<>();
			final List<Member> mes = AuthenServerUtils.getFollowList(userId);
			if (mes != null && mes.size() > 0) {
				StringBuilder sb = new StringBuilder();
				for (Member me : mes) {
					sb.append(me.getId());
					sb.append(",");
				}
				if (sb.length() > 0) {
					sb.setLength(sb.length() - 1);
					List<LiveRoom> lists = roomService.getByUserIds(sb.toString());
					for (LiveRoom live : lists) {
						Room vo = Convertor.roomConvert2Vo(live);
						vos.add(vo);
					}
				}
			}
			ret.setCode(0);
			ret.setList(vos);
			ret.setMessage(Global.SUCCESS);
		} catch (Exception e) {
			logger.error(e.getMessage());
			ret.setCode(10);
			ret.setMessage(Global.FAILED);
		}
		return ret.toString();
	}

	/**
	 * 通过房间ID查询当前房间用户列表
	 * 
	 * @param roomId
	 *            房间ID
	 * @return 返回房间用户列表
	 */
	@RequestMapping(method = RequestMethod.GET, value = "/queryRoomUsers")
	public @ResponseBody String queryRoomUsers(@RequestParam("roomId") String roomId) {
		ReturnList ret = new ReturnList();
		try {
			List<UserVo> vos = getUseListByRoomId(roomId);
			ret.setCode(0);
			ret.setList(vos);
			ret.setMessage(Global.SUCCESS);
		} catch (Exception e) {
			logger.error(e.getMessage());
			ret.setCode(10);
			ret.setMessage(Global.FAILED);
		}
		return ret.toString();
	}

	private List<UserVo> getUseListByRoomId(String roomId) throws Exception {
		LiveUserRoom userRoom = new LiveUserRoom();
		userRoom.setRoomId(roomId);
		List<LiveUserRoom> userRooms = liveUserRoomService.findList(userRoom);
		List<UserVo> vos =  Lists.newCopyOnWriteArrayList(); //new ArrayList<>();
		if (userRooms == null || userRooms.isEmpty()) {
			return vos;
		}
		// final List<Member> mes = AuthenServerUtils.getUserList();
		// for (Member m : mes) {
		CompletableFuture<Member> future = null;
		for (LiveUserRoom r : userRooms) {
			String userId = r.getUserId();
			future = CompletableFuture.supplyAsync(() -> {
				//System.out.println("------------------->Enter supply!");
				Member m = AuthenServerUtils.getUser(userId);
				return m;
			});
			future.thenAcceptAsync((m)->{
				if (m != null) {
					UserVo user = new UserVo();
					user.setNickName(m.getNickname());
					user.setPhoto(m.getAvatar());
					user.setId(m.getId().toString());
					user.setUserType(m.getType());
					user.setSex(m.getSex());
					vos.add(user);
					//System.out.println("------------------->Enter Accept!");
				}
			});
		}
		
		if (future != null) {
			logger.info("---------->get=" + future.get());
		}
		
		// }
		return vos;
	}

	/**
	 * 查询一个房间在线用户列表
	 * 
	 * @param roomId
	 *            房间ID
	 * @return
	 */
	@RequestMapping(method = RequestMethod.GET, value = "/queryRoomOnlineUsers")
	public @ResponseBody String queryRoomOnlineUsers(@RequestParam("roomId") String roomId) {
		ReturnList ret = new ReturnList();
		try {
			List<UserVo> vos = getUseListByRoomId(roomId);
			ret.setCode(0);
			ret.setList(vos);
			ret.setMessage(Global.SUCCESS);
		} catch (Exception e) {
			logger.error(e.getMessage());
			ret.setCode(10);
			ret.setMessage(Global.FAILED);
		}
		return ret.toString();
	}

	/**
	 * 查询当前房间用户列表
	 * 
	 * @param owner
	 *            主播user id
	 * @return 返回房间用户列表
	 */
	@RequestMapping(method = RequestMethod.GET, value = "/queryOnlineUsers")
	public @ResponseBody String queryOnlineUsers(@RequestParam("owner") String owner) {
		ReturnList ret = new ReturnList();
		try {
			LiveRoom liveRoom = roomService.getByOwner(owner);
			if (liveRoom == null) {
				ret.setMessage("The owner can not found any avialable room!");
				ret.setCode(1);
				return JsonUtils.toJson(ret);
			}
			List<UserVo> vos = getUseListByRoomId(liveRoom.getId());
			ret.setCode(0);
			ret.setList(vos);
			ret.setMessage(Global.SUCCESS);
		} catch (Exception e) {
			logger.error(e.getMessage());
			ret.setCode(10);
			ret.setMessage(Global.FAILED);
		}
		return ret.toString();
	}

	/**
	 * 查看房间金币贡献值用户排行列表
	 * 
	 * @param roomId
	 *            房间ID
	 * @return 返回金币排行列表
	 */
	@RequestMapping(method = RequestMethod.GET, value = "/queryGoldContribution")
	public @ResponseBody String queryGoldContribution(@RequestParam("roomId") String roomId,
			@RequestParam(value = "pageIndex", required = false, defaultValue = "1") Integer pageIndex,
			@RequestParam(value = "pageSize", required = false, defaultValue = "100") Integer pageSize) {
		ReturnList ret = new ReturnList();
		try {
			LiveRoom liveRoom = roomService.get(roomId);
			if (liveRoom == null) {
				ret.setCode(1);
				ret.setMessage("The room is not exist!");
				return ret.toString();
			}
			LiveGoldContribution entity = new LiveGoldContribution();
			entity.setUserId(liveRoom.getUserId());
			Page<LiveGoldContribution> page = new Page<LiveGoldContribution>(pageIndex, pageSize);
			page.setOrderBy("a.count desc,a.create_date desc ");
			List<LiveGoldContribution> lists = liveGoldContributionService.findPage(page, entity).getList();
			List<GoldContribution> vos = new ArrayList<>();
			for (LiveGoldContribution live : lists) {
				GoldContribution vo = Convertor.GoldContributionConvert2Vo(live, roomId);
				vos.add(vo);
			}
			ret.setCode(0);
			ret.setMessage(Global.SUCCESS);
			ret.setList(vos);
		} catch (Exception e) {
			logger.error(e.getMessage());
			ret.setCode(10);
			ret.setMessage(Global.FAILED);
		}
		return ret.toString();
	}

	/**
	 * 添加点赞
	 * 
	 * @param roomId
	 *            房间Id
	 * @param userId
	 *            用户Id
	 * @param count
	 *            点赞数
	 * @return
	 */
	@RequestMapping(method = RequestMethod.POST, value = "/addClickAlike")
	public @ResponseBody String addClickAlike(@RequestParam("roomId") String roomId,
			@RequestParam("userId") String userId, @RequestParam("count") Long count) {
		Status ret = new Status();
		try {
			LiveClickAlike like = new LiveClickAlike();
			like.setAmount(count);
			like.setUserId(userId);
			like.setRoomId(roomId);
			like.setCreateDate(new Date());
			liveClickAlikeService.save(like);
			ret.setCode(0);
			ret.setMessage(Global.SUCCESS);
		} catch (Exception e) {
			logger.error(e.getMessage());
			ret.setCode(10);
			ret.setMessage(Global.FAILED);
		}
		return JsonUtils.toJson(ret);
	}

	/**
	 * 查询某个房间的点赞数
	 * 
	 * @param roomId
	 * @return
	 */
	@RequestMapping(value = "/queryClickAlike")
	public @ResponseBody String queryClickAlike(@RequestParam("roomId") String roomId) {
		ReturnList ret = new ReturnList();
		try {
			List<LiveClickAlike> lists = liveClickAlikeService.findCountList(roomId);
			List<ClickAlikeVo> vos = new ArrayList<>();
			for (LiveClickAlike li : lists) {
				vos.add(ClickAlikeVo.convertor(li));
			}
			ret.setCode(0);
			ret.setList(vos);
			ret.setMessage(Global.SUCCESS);
		} catch (Exception e) {
			logger.error(e.getMessage());
			ret.setCode(10);
			ret.setMessage(Global.FAILED);
		}
		return ret.toString();
	}

	/**
	 * 用户提交举报数据
	 * 
	 * @param tipJson
	 * @return
	 */
	@RequestMapping(method = RequestMethod.POST, value = "/addTipOffs")
	public @ResponseBody String addTipOffs(@RequestParam("tipOffs") String tipJson) {
		Status ret = new Status();
		try {
			LiveTipOffs tip = new LiveTipOffs();
			String param = Encodes.urlDecode(Encodes.unescapeHtml(tipJson));
			logger.info("addTipOffs data======>" + param);
			tip = JsonUtils.fromJson(param, LiveTipOffs.class);
			tip.setCreateDate(new Date());
			tip.setFlag(0);
			tip.setState(0);
			liveTipOffsService.save(tip);
			ret.setCode(0);
			ret.setMessage(Global.SUCCESS);
		} catch (Exception e) {
			logger.error(e.getMessage());
			ret.setCode(10);
			ret.setMessage(Global.FAILED);
		}
		return JsonUtils.toJson(ret);
	}

	/**
	 * 查询在线人数。
	 * @param roomId
	 * @return
	 */
	@RequestMapping(value = "/getOnlineNumber", method = RequestMethod.GET)
	public @ResponseBody String getOnlineNumber(@RequestParam("roomId") String roomId) {
		ReturnStatus ret = new ReturnStatus();
		try {
			ret.setCode(0);
			ret.setMessage(Global.SUCCESS);
			Long onlineNumber = liveUserRoomService.getOnlineNumberByRoom(roomId);
			Map<String, Object> obj = new HashMap<>();
			obj.put("onlineNumber", onlineNumber);
			ret.setItem(obj);
		} catch (Exception e) {
			logger.error(e.getMessage());
			ret.setCode(10);
			ret.setMessage(Global.FAILED);
		}
		return ret.toString();
	}

}
